package com.haojiang.mh.remote.utils

import android.Manifest
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCharacteristic
import android.content.Context
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.TextUtils
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import cn.com.heaton.blelibrary.ble.Ble
import cn.com.heaton.blelibrary.ble.callback.BleConnectCallback
import cn.com.heaton.blelibrary.ble.callback.BleNotifyCallback
import cn.com.heaton.blelibrary.ble.callback.BleScanCallback
import cn.com.heaton.blelibrary.ble.callback.BleWriteCallback
import cn.com.heaton.blelibrary.ble.model.BleDevice
import cn.com.heaton.blelibrary.ble.model.ScanRecord
import cn.com.heaton.blelibrary.ble.utils.ByteUtils
import cn.com.heaton.blelibrary.ble.utils.ThreadUtils
import com.haojiang.mh.AppContext
import com.haojiang.mh.R
import com.haojiang.mh.remote.base.BaseSurface
import com.haojiang.mh.remote.bean.*
import com.haojiang.mh.remote.enums.EConnect
import com.haojiang.mh.remote.event.BedImgEvent
import com.haojiang.mh.remote.event.BleEvent
import com.haojiang.mh.remote.event.BleStatus
import com.haojiang.mh.remote.event.ReceiverEvent
import com.haojiang.mh.remote.utils.Constant.RX_HEADER
import com.haojiang.mh.remote.utils.Constant.TX_ALARM
import com.haojiang.mh.remote.utils.Constant.TX_AROMA
import com.haojiang.mh.remote.utils.Constant.TX_END
import com.haojiang.mh.remote.utils.Constant.TX_EXIT_ONE_MIN
import com.haojiang.mh.remote.utils.Constant.TX_LED
import com.haojiang.mh.remote.utils.Constant.rxList
import com.haojiang.mh.remote.utils.SpUtil.SECTION_BLE_GROUP
import com.haojiang.mh.remote.utils.SpUtil.SECTION_BLE_MODIFY
import com.haojiang.mh.remote.widget.RmText
import org.greenrobot.eventbus.EventBus
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.collections.ArrayList

class BleUtil {

    companion object {


        val KEY_GROUP = "key_group"
        private val txIntervalTime = 150L

        //        private val BLE_INTERFACE = "ble_interface"
        private val context: Context = AppContext.instance()


        //        var lastBleRssiDevice: BleRssiDevice? = null
        val groupData = GroupData()
        val lastConnect = LastConnect()
//        var lastConnectType: Int = NORMAL_SINGLE
//        var lastConnectId: Long = 0L
//        val lastBleDeviceList = arrayListOf<BleRssiDevice>()

//        //要显示的主功能界面
//        val fragMainList = arrayListOf<Int>()
//        //要显示的次功能界面
//        val fragExtraList = ArrayList<Int>()

        //        val ble = Ble.getInstance<BleRssiDevice>()
        val ble = Ble.getInstance<BleRssiDevice>()
        val bleRssiDeviceList = arrayListOf<BleRssiDevice>()        //距离蓝牙设备列表
        val bytes: ByteArray = byteArrayOf(0, 0, 0, 0, 0)
        var totalByte: Int = 0
        val connectMap = LinkedHashMap<String, ConnectGroup>()    //组类型信息

        val permissionArr = arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.CAMERA,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
        )

//        val keepAliveDevieList = ArrayList<BleRssiDevice>()
//
//        val keepAliveHandler = object : Handler(Looper.getMainLooper()) {
//            override fun handleMessage(msg: Message) {
//
//                keepAliveDevieList.clear()
//                lastConnect.bleDeviceList.forEach {
//                    if (it.isConnecting) {
//                        this.sendEmptyMessageDelayed(0, 8000)
//                        return
//                    }
//                    if (it.isDisconnected) {
//                        keepAliveDevieList.add(it)
//                    }
//                }
//                if (keepAliveDevieList.size > 0) {
//                    ble.connects(keepAliveDevieList, connectCallback)
//                }
//                this.sendEmptyMessageDelayed(0, 8000)
//            }
//        }

        val frontHandler = Handler(Looper.getMainLooper())  //前面数据处理handler

        val sendHandler: Handler = object : Handler(Looper.getMainLooper()) {   //发送handler
            override fun handleMessage(msg: Message) {
//                super.handleMessage(msg)

                if (msg.obj != null) {
                    when (msg.what) {
                        context.getString(R.string.press_keep).toInt() -> {
                            val bytes = (msg.obj) as ByteArray
//                            LogUtil.e(bytes.toList().toString() + "=KEEP")
                            dataSend(bytes)
                            Thread.sleep(txIntervalTime)
                            val message = Message.obtain()
                            message.copyFrom(msg)
                            this.sendMessage(message)
                        }

                        context.getString(R.string.press_once).toInt() -> {
                            val bytes = (msg.obj) as ByteArray
//                            LogUtil.e(bytes.toList().toString() + "=ONCE")
                            dataSend(bytes)
//                            Thread.sleep(intervalTime)
//                            dataCancel()
                        }

                        //结束符
//                        AppContext.getInstance().getString(R.string.press_end).toInt() -> {
//                            val bytes = (msg.obj) as ByteArray
//                            LogUtil.e(bytes.toList().toString() + "=END")
//                            this.removeCallbacksAndMessages(null)
//                            dataSend(bytes)
//                        }
                    }
                }
            }
        }

        private val surfacePrifix = "com.haojiang.mh.remote.surface.F"

        //TODO
        //判断l蓝牙广播的编号是否存在
        @Synchronized
        fun isSurfaceExist(surfaceNo: String): Boolean {
            var surfaceClass: Class<BaseSurface>? = null
            try {
                val _surfaceNo =surfacePrifix  + surfaceNo.toLowerCase(Locale.ROOT)
//                LogUtil.e(_surfaceNo + "=界面=" + surfacePrifix)
                surfaceClass = Class.forName(_surfaceNo) as Class<BaseSurface>
            } catch (e: Exception) {
//                LogUtil.e(surfaceClass.toString() + "=11")
            } finally {
//                LogUtil.e(surfaceClass.toString() + "22")
                return surfaceClass != null
            }
        }

        //根据给出的蓝牙广播编号获取界面信息 排除QRRM
        @Synchronized
        fun getSurface(surfaceNo: String): BaseSurface? {
            var surface: BaseSurface? = null
            try {
                val _surfaceNo =surfacePrifix  + surfaceNo.toLowerCase(Locale.ROOT)
                val surfaceClass: Class<BaseSurface>? =
                    Class.forName(_surfaceNo) as Class<BaseSurface>?
                surfaceClass?.let {
                    surface = it.newInstance()
                }
            } catch (e: Exception) {
            } finally {
                return surface
            }
        }


        /**
         * 扫描后回调
         */
        val scanCallback: BleScanCallback<BleRssiDevice> =
            object : BleScanCallback<BleRssiDevice>() {
                override fun onLeScan(device: BleRssiDevice, rssi: Int, scanRecord: ByteArray) {

                    if (TextUtils.isEmpty(device.bleName) || device.bleName.length < 4) return
                    val surfaceName = device.bleName.substring(0, 4)
//                    LogUtil.e(surfaceName+ "==蓝牙名称3")
//                LogUtil.e(SurfaceKey.keyMap.containsKey(interfaceName).toString() + "--蓝牙界面")
//                    if (!SurfaceKey.keyMap.containsKey(interfaceName)) return
                    if (!isSurfaceExist(surfaceName)) return

//                LogUtil.e("扫描到的蓝牙=" + device.bleName + "=" + device.bleAddress)

                    synchronized(ble.locker) {
                        for (i in bleRssiDeviceList.indices) {
                            val bleRssiDevice: BleRssiDevice = bleRssiDeviceList.get(i)
                            if (TextUtils.equals(bleRssiDevice.bleAddress, device.bleAddress)) {
                                if (bleRssiDevice.rssi != rssi && System.currentTimeMillis() - bleRssiDevice.rssiUpdateTime > 5000L) {
                                    bleRssiDevice.rssiUpdateTime = System.currentTimeMillis()
                                    bleRssiDevice.rssi = rssi
                                    EventBus.getDefault().post(
                                        BleEvent(
                                            BleStatus.SCAN_RSSI_CHANGED,
                                            data = i.toString()
                                        )
                                    )
                                }
                                return
                            }
                        }
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            device.scanRecord = ScanRecord.parseFromBytes(scanRecord)
                        }
                        device.rssi = rssi
                        //如果读取到的保存的设备mac地址的设备别名不为空
                        val deviceAlias = readDeviceAlias(device.bleAddress)
                        if (TextUtils.isEmpty(deviceAlias)) {
                            device.deviceAlias = device.bleName
                        } else {
                            device.deviceAlias = deviceAlias
                        }
//                    LogUtil.e(deviceAlias + "=别名")
                        bleRssiDeviceList.add(device)
                        EventBus.getDefault().post(BleEvent(BleStatus.SCAN_FOUND))
                    }

                }


                override fun onStart() {
                    super.onStart()
//            startBannerLoadingAnim()
                }

                override fun onStop() {
                    super.onStop()
                    EventBus.getDefault().post(BleEvent(BleStatus.SCAN_STOP))
//            stopBannerLoadingAnim()
                }

                override fun onScanFailed(errorCode: Int) {
                    super.onScanFailed(errorCode)
                    Toast.makeText(context, "扫描失败" + errorCode, Toast.LENGTH_SHORT).show()
                    LogUtil.e("onScanFailed: $errorCode")
                }
            }

        //保存设备别名
        @Synchronized
        fun saveDeviceAlias(bleAddress: String, deviceAlias: String): Boolean {
            if (SpUtil.putData(context, SECTION_BLE_MODIFY, bleAddress, deviceAlias)) {
                return true
            }
            return false
        }

        //读取设备别名
        @Synchronized
        fun readDeviceAlias(bleAddress: String): String {
            val deviceAlias = SpUtil.getData(context, SECTION_BLE_MODIFY, bleAddress, "") as String
            return deviceAlias
        }

        val connectCallback: BleConnectCallback<BleRssiDevice> =
            object : BleConnectCallback<BleRssiDevice>() {

                @Synchronized
                override fun onConnectionChanged(device: BleRssiDevice) {
                    if (device.isConnected) {
//                    LogUtil.e(device.bleName + "==已連接了groupid =" + lastGroupId + "== type=" + lastGroupType)
                        EventBus.getDefault().post(BleEvent(BleStatus.GATT_CONNECT))
                        LogUtil.e("已连接")
                    } else if (device.isConnecting) {
                        LogUtil.e("连接中")
//                actionBar.setSubtitle("连接中...")
                    } else if (device.isDisconnected) {
                        LogUtil.e("未连接")
//                    devDisconnect(device)   //断开单个连接
                        EventBus.getDefault().post(BleEvent(BleStatus.DISCONNECT_PASSIVE, device))
                    }
                }

                @Synchronized
                override fun onConnectException(device: BleRssiDevice, errorCode: Int) {
                    super.onConnectException(device, errorCode)
                    EventBus.getDefault()
                        .post(BleEvent(BleStatus.CONNECT_EXCEPTION, data = errorCode.toString()))
//                showToast("连接异常，异常状态码:" + device.bleName + "=" + errorCode)
                    LogUtil.e("连接异常，异常状态码:$errorCode")
                }

                @Synchronized
                override fun onConnectTimeOut(device: BleRssiDevice) {
                    super.onConnectTimeOut(device)
                    EventBus.getDefault().post(BleEvent(BleStatus.CONNECT_TIME_OUT))
//                showToast("连接超时:" + device.bleName)
                    LogUtil.e("onConnectTimeOut: " + device.bleName)
                }

                @Synchronized
                override fun onConnectCancel(device: BleRssiDevice) {
                    super.onConnectCancel(device)
//            showToast("连接取消:" + device.bleName)
                    LogUtil.e("onConnectCancel: " + device.bleName)
                }

                @Synchronized
                override fun onServicesDiscovered(device: BleRssiDevice, gatt: BluetoothGatt) {
                    super.onServicesDiscovered(device, gatt)

                    if (lastConnect.connectType == EConnect.CONNECT_SINGLE.data) {
                        UuidUtil.curUuidMap.clear()
                        device.isSend = true
                    } else {
                        device.isSend = isDeviceSend(device)
                    }
                    val uuidBean = GattBean()
                    UuidUtil.curUuidMap.put(device, uuidBean)
//                LogUtil.e("服务" + UuidUtil.curUuidMap.size.toString() + "==" + UuidUtil.curUuidMap.toString())

                    for (entry in UuidUtil.uuidMap.entries) {
                        val service = gatt.getService(entry.key)
                        if (service != null) {
                            uuidBean.manufacturer = entry.value.manufacturer
                            uuidBean.service = service

                            val characteristicWrite =
                                service.getCharacteristic(entry.value.characteristicWrite)
                            // 可写，注：要 & 其可写的两个属性
                            val charaPropWrite = characteristicWrite.getProperties()
                            if (charaPropWrite and BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE > 0
                                || charaPropWrite and BluetoothGattCharacteristic.PROPERTY_WRITE > 0
                            ) {
                                uuidBean.characteristicWrite = characteristicWrite
                            }
                            val characteristicRead =
                                service.getCharacteristic(entry.value.characteristicRead)
                            val charaPropRead = characteristicRead.getProperties()
                            if (charaPropRead and BluetoothGattCharacteristic.PROPERTY_NOTIFY > 0
                                || charaPropRead and BluetoothGattCharacteristic.PROPERTY_INDICATE > 0
                            ) {
                                uuidBean.characteristicRead = characteristicRead
                                setSubscription(device, service.uuid, characteristicRead.uuid)
                            }
                            break
                        }
                    }
                    TimeUnit.MILLISECONDS.sleep(100)
                    if (uuidBean.service != null
                        && uuidBean.characteristicWrite != null
                        && uuidBean.characteristicRead != null
                    ) {
//                    LogUtil.e(UuidUtil.curUuidMap.size.toString() + "= 最后设备连接的设备数量")
                        EventBus.getDefault().post(BleEvent(BleStatus.GATT_SERVICE_CONNECT, device))
                    } else {
                        devDisconnect(device)
//                    EventBus.getDefault().post(BleEvent(BleStatus.GATT_SERVICE_DISCONNECT, device))
                    }
                }
            }

        @Synchronized
        fun devScan() {
            if (ble.isBleEnable && !ble.isScanning) {
                EventBus.getDefault().post(BleEvent(BleStatus.SCAN_PREPARE))
                ThreadUtils.asyn {
                    Thread.sleep(600)
                    ble.startScan(scanCallback)
                }
            }
        }

        //更新是否发送
//        fun updateSend(device: BleRssiDevice) {
//            groupMap.forEach {
//                val groupValueList = it.value.groupValueList
//                groupValueList.forEach {
//                    if (it.bleRssiDevice.bleAddress.equals(device.bleAddress)) {
//                        device.isSend = it.isSend
//                        return
//                    }
//                }
//            }
//        }

        //断开单个连接
        @Synchronized
        fun devDisconnect(bleDevice: BleRssiDevice) {
            if (ble.isBleEnable) {
                LogUtil.e("已经断开")
                if (bleDevice.isConnecting) {
                    ble.cancelConnecting(bleDevice)
                    ble.refreshDeviceCache(bleDevice.bleAddress)
                } else if (bleDevice.isConnected) {
                    ble.disconnect(bleDevice)
                    ble.refreshDeviceCache(bleDevice.bleAddress)
                }
            }
        }
//        @Synchronized
//        fun devDisconnect(bleDevice: BleRssiDevice) {
//            LogUtil.e(ble.isBleEnable.toString() + "=连接数量=" + ble.connectedDevices.size + "断开之前")
//            if (ble.isBleEnable && ble.connectedDevices.size > 0) {
//                LogUtil.e("已经断开")
//                if (bleDevice.isConnecting) {
//                    ble.cancelConnecting(bleDevice)
//                    ble.refreshDeviceCache(bleDevice.bleAddress)
//                } else if (bleDevice.isConnected) {
//                    ble.disconnect(bleDevice)
//                    ble.refreshDeviceCache(bleDevice.bleAddress)
//                }
//            }
//        }

        @Synchronized
        fun devDisconnectAll() {

//            LogUtil.e(UuidUtil.curUuidMap.size.toString() + " uuid数量断开之前" + Thread.currentThread().name)
//            keepAliveHandler.removeCallbacksAndMessages(null)
            if (ble.isBleEnable) {
                ble.cancelConnectings(lastConnect.bleDeviceList)
                ble.disconnectAll()
                val bleDeviceList = ArrayList<BleRssiDevice>()
                bleDeviceList.addAll(ble.connectedDevices)
                bleDeviceList.forEach {
                    if (it.isConnecting) {
                        ble.cancelConnecting(it)
                        ble.refreshDeviceCache(it.bleAddress)
                    } else {
                        ble.disconnect(it)
                        ble.refreshDeviceCache(it.bleAddress)
                    }
                }

                UuidUtil.curUuidMap.forEach {
                    if (it.key.isConnecting) {
                        ble.cancelConnecting(it.key)
                        ble.refreshDeviceCache(it.key.bleAddress)
                    } else if (it.key.isConnected) {
                        ble.disconnect(it.key)
                        ble.refreshDeviceCache(it.key.bleAddress)
                    }
                }
                ble.connectedDevices.clear()
                UuidUtil.curUuidMap.clear()
//                LogUtil.e(UuidUtil.curUuidMap.size.toString() + " 已经全部断开")
            }
        }


        //连接单个设备或者多个设备  因为有测试功能需要所以
        @Synchronized
        fun devConnects(bleDeviceList: ArrayList<BleRssiDevice>) {
            if (ble.isBleEnable) {
//                ThreadUtils.ui {
//                    Util.showLoading(context, null)
//                }
                if (ble.isScanning) {
                    ble.stopScan()
                }
                devDisconnectAll()
//                ble.connectedDevices.clear()
//                UuidUtil.curUuidMap.clear()
//                LogUtil.e("开始连接--connectedDevices已连接的数量=" + ble.connectedDevices.size.toString())
                ble.connects(bleDeviceList, connectCallback)
//                keepAliveHandler.sendEmptyMessageDelayed(0, 10000)
            }
        }

        @Synchronized
        fun devReconnect() {
            if (ble.isBleEnable && lastConnect.bleDeviceList.size > 0) {
                ble.connects(lastConnect.bleDeviceList, connectCallback)
            }
        }


        //判断是否有连接的设备
        fun isDevConncted(): Boolean {
            if (UuidUtil.curUuidMap.size <= 0) return false
            UuidUtil.curUuidMap.forEach {
                return it.key.isConnected
            }
            return false
        }

//        /**
//         * 检测码值校验和
//         * @param buffer
//         * @return
//         */
//        fun chkSumNew(buffer: String): Boolean {
//            var sum = 0
//            var index = 0
////            println(buffer.length.toString() + "--")
//            while (index < buffer.length) {
//                if (index == buffer.length - 2) {
//                    return if (sum % 256 == ByteUtils.hexToInt(
//                            buffer.substring(
//                                index,
//                                index + 2
//                            )
//                        )
//                    ) { //                    Log.e(TAG, "验证通过=" + sum);
//                        true
//                    } else { //                    Log.e(TAG, "验证没通过");
//                        false
//                    }
//                } else {
//                    sum = sum + ByteUtils.hexToInt(buffer.substring(index, index + 2))
//                }
//                index = index + 2
//            }
//            return false
//        }


        /**
         * 检测码值校验和
         * @param buffer
         * @return
         */
        fun chkSum(buffer: String): Boolean {
            var sum = 0
            var index = 0
//            println(buffer.length.toString() + "--")
            while (index < buffer.length) {
                if (index == buffer.length - 2) {
                    return if (sum % 256 == ByteUtils.hexToInt(
                            buffer.substring(
                                index,
                                index + 2
                            )
                        )
                    ) { //                    Log.e(TAG, "验证通过=" + sum);
                        true
                    } else { //                    Log.e(TAG, "验证没通过");
                        false
                    }
                } else {
                    sum = sum + ByteUtils.hexToInt(buffer.substring(index, index + 2))
                }
                index = index + 2
            }
            return false
        }


        private fun getPack(pack: String, singleLen: Int): String? {
            var packStr = pack
            packStr = packStr.toLowerCase()
//            var index = 0
            var len = 0
            val totalLen = packStr.length
            var subPack = packStr
            var chkStr: String
            for (i in rxList.indices) {
                while (len <= totalLen) {
                    val index = subPack.indexOf(rxList.get(i))
                    if (index != -1) {
                        if (index + singleLen > subPack.length) break
                        chkStr = subPack.substring(index, index + singleLen) //获取单包长度
                        if (chkSum(chkStr)) {
                            return chkStr
                        }
                        len = len + index + 4
                        subPack = packStr.substring(len, totalLen)
                    } else {
                        break
                    }
                }
                len = 0
            }
            return ""
        }

        private fun bufferClear() {
            if (mBuffer.toString().endsWith(RX_HEADER)) {
                mBuffer.setLength(0);
                mBuffer.append(RX_HEADER);
            } else {
                mBuffer.setLength(0);
            }
        }

        private val mBuffer = StringBuffer()
        private const val DATA_TABLE_LEN = 32
        //            private String mAltitude = null;
//        private var mHexStr: String? = null

        //订阅回调
        fun setSubscription(
            device: BleRssiDevice,
            serviceUuid: UUID?,
            characteristicReadUuid: UUID?
        ) {

            Ble.getInstance<BleDevice>().enableNotifyByUuid(
                device,
                true,
                serviceUuid,
                characteristicReadUuid,
                object : BleNotifyCallback<BleDevice?>() {
                    override fun onChanged(
                        device: BleDevice?,
                        characteristic: BluetoothGattCharacteristic
                    ) {
                        LogUtil.e(ByteUtils.bytes2HexStr(characteristic.value) + " 回调")

                        val mHexStr =
                            ByteUtils.bytes2HexStr(characteristic.value).toLowerCase(Locale.ROOT);

                        if (mHexStr.startsWith(RX_HEADER) && mBuffer.length > 100) {
                            mBuffer.setLength(0)
                        }

                        mBuffer.append(mHexStr)

//                        if(mBuffer.equals("6D06"))

//                Log.e(TAG, "onCharacteristicChanged: " + mBuffer + "=" + mBuffer.length());

                        if (mBuffer.length < 10) {                                        //如果不足10个字节
                            return;
                        } else if (mBuffer.length >= 10 && mBuffer.length < DATA_TABLE_LEN) {                            //如果等于10个字节

                            val packStr = getPack(mBuffer.toString(), 10);              //处理10个字节的数据
                            if (packStr != null) {
                                EventBus.getDefault().post(ReceiverEvent(packStr))
                            }

                            if (!TextUtils.isEmpty(packStr)) {
                                bufferClear();
                            }
                        }
                    }

                    override fun onNotifySuccess(device: BleDevice?) {
                        super.onNotifySuccess(device)
                        LogUtil.e(device!!.bleName + "=订阅成功")
                        val bleRssiDevice = device as BleRssiDevice

//                        val taskList: ArrayList<TaskData> = arrayListOf(
////                            TaskData(Runnable { deviceDataSend(bleRssiDevice, DATA_TX_INIT) }, 300),
//                            TaskData(Runnable {
//                                TimeUnit.MILLISECONDS.sleep(300)
//                                deviceDataSend(bleRssiDevice, DATA_TX_INIT)
//                            }, 300),
//                            TaskData(Runnable {
//                                deviceDataSend(bleRssiDevice, DATA_TX_QUERY_MOTOR)
//                            }, 300),
//                        )

                        val taskList: ArrayList<TaskData> = arrayListOf(
                            TaskData(
                                Runnable { deviceDataSend(bleRssiDevice, TX_EXIT_ONE_MIN) },
                                300
                            ),
                            TaskData(Runnable { deviceDataSend(bleRssiDevice, TX_ALARM) }, 300),
                            TaskData(Runnable { deviceDataSend(bleRssiDevice, TX_LED) }, 300),
                            TaskData(Runnable { deviceDataSend(bleRssiDevice, TX_AROMA) }, 300)
                        )
                        taskRun(taskList)
                    }

                    override fun onNotifyCanceled(device: BleDevice?) {
                        super.onNotifyCanceled(device)
                        LogUtil.e("订阅取消")
                    }
                })
        }


        @Synchronized
        fun taskRun(taskList: ArrayList<TaskData>) {
            if (taskList.size == 0) {
                return
            }
            Thread(Runnable {
                taskList.forEach {
                    it.task.run()
                    TimeUnit.MILLISECONDS.sleep(it.delayMs)
                }
            }).start()
        }

        private val bleWriteCallback = object : BleWriteCallback<BleRssiDevice>() {
            override fun onWriteSuccess(
                device: BleRssiDevice?,
                characteristic: BluetoothGattCharacteristic
            ) {
                LogUtil.e(
                    "onWriteSuccess: " + device!!.bleName + "=" + ByteUtils.bytes2HexStr(
                        characteristic.getValue()
                    )
                )
            }

            override fun onWriteFailed(device: BleRssiDevice?, failedCode: Int) {
//                LogUtil.e("onWiteFailed: $failedCode")
            }
        }

        fun deviceDataSend(bleRssiDevice: BleRssiDevice?, data: ByteArray) {
            if (!bleRssiDevice!!.isConnected) return
            val gattBean = UuidUtil.curUuidMap.get(bleRssiDevice)
            if (gattBean != null) {
                ble.writeByUuid(
                    bleRssiDevice,
                    data,
                    gattBean.service!!.uuid,
                    gattBean.characteristicWrite!!.uuid,
                    bleWriteCallback
                )
            }
        }

        //数据发送
        @Synchronized
        fun dataSend(data: ByteArray) {
            if (!isDevConncted()) return

            UuidUtil.curUuidMap.forEach {
                val bleDevice = it.key
                if (bleDevice.isSend) {
                    val gattBean = it.value
                    ble.writeByUuid(
                        bleDevice,
                        data,
                        gattBean.service!!.uuid,
                        gattBean.characteristicWrite!!.uuid,
                        bleWriteCallback
                    )
                }
            }

//            if (lastGroupType == GROUP_TYPE_NONE) {             //单个f发送
//                UuidUtil.curUuidMap.forEach {
//                    val bleDevice = it.key
//                    val gattBean = it.value
//                    ble.writeByUuid(
//                        bleDevice,
//                        data,
//                        gattBean.service!!.uuid,
//                        gattBean.characteristicWrite!!.uuid,
//                        bleWriteCallback
//                    )
//                }
////                val gattBean = UuidUtil.curUuidMap.get(bleDevice)
////                if (gattBean != null) if (gattBean.service != null &&
////                    gattBean.characteristicWrite != null &&
////                    gattBean.characteristicRead != null
////                ) {
////                    ble.writeByUuid(
////                        bleDevice,
////                        data,
////                        gattBean.service!!.uuid,
////                        gattBean.characteristicWrite!!.uuid,
////                        bleWriteCallback
////                    )
////                }
//            } else { //组发送
//
//            }


//            val ble = Ble.getInstance<BleDevice>()
//            if (ble.connectedDevices.size > 0) {
//                LogUtil.e(ble.connectedDevices.size.toString() + "=connectedDevices.size的数量=")
//                if (lastGroupType == GROUP_TYPE_NONE) { //如果是单个连接
//                    val bleDevice = ble.connectedDevices.get(0)
//                    ble.writeByUuid(
//                        bleDevice,
//                        data,
//                        UuidUtil.curUuidMap.get(UUID_SERVICE),
//                        UuidUtil.curUuidMap.get(UUID_CHARACTERISTIC_WRITE),
//                        bleWriteCallback
//                    )
//                } else {
//                    ble.connectedDevices.forEach {
//                        //多个连接
//                        ble.writeByUuid(
//                            it,
//                            data,
//                            UuidUtil.curUuidMap.get(UUID_SERVICE),
//                            UuidUtil.curUuidMap.get(UUID_CHARACTERISTIC_WRITE),
//                            bleWriteCallback
//                        )
//                    }
//                }
        }


        //数据取消结束符
        fun dataCancel() {
//            if (UuidUtil.curUuidMap.get(UUID_SERVICE) == null ||
//                UuidUtil.curUuidMap.get(UUID_CHARACTERISTIC_WRITE) == null
//            ) return
//            if (UuidUtil.curUuidMap.size <= 0) return
            if (!isDevConncted()) return
            dataSend(TX_END)
        }

        //命令结束
//        fun cmdEnd(view: RmImageView) {
        fun cmdEnd(view: RmText) {
            dataCancel()
            if (!view.img.equals(context.getString(R.string.bed_ubl))) {
                view.img?.let {
                    EventBus.getDefault().post(BedImgEvent(context.getString(R.string.bed_none)))
                }
            }
        }

        //按键数据回调
        val onTouchListener = object : View.OnTouchListener {

            override fun onTouch(view: View?, event: MotionEvent?): Boolean {
//                if (event != null && view != null && view is RmImageView) {
                if (event != null && view != null && view is RmText) {
                    when (event.action) {

                        MotionEvent.ACTION_DOWN -> {
                            onActionDown(view)
                        }

                        MotionEvent.ACTION_MOVE -> {
                            if (inRangeOfView(view, event.rawX.toInt(), event.rawY.toInt())) {
                                onActionUp(view)
                            }
                        }

                        MotionEvent.ACTION_CANCEL,
                        MotionEvent.ACTION_UP -> {
                            onActionUp(view)
                        }
                    }
                }
                return false
            }
        }


        //按键按下
        fun onActionDown(view: RmText) {
//            if (ble.isBleEnable && UuidUtil.curUuidMap.get(UUID_SERVICE) != null ||
//                UuidUtil.curUuidMap.get(UUID_CHARACTERISTIC_WRITE) != null
//            )
            if (ble.isBleEnable && UuidUtil.curUuidMap.size > 0) {
                frontHandler.postDelayed(Runnable {
                    view.code?.let {
                        view.pressType?.let {
                            val msg = Message.obtain()
                            msg.what = view.pressType!!.toInt()
                            bytes[0] = 0x6E
                            bytes[1] = 0x01
                            bytes[2] = 0x00
                            bytes[3] = ByteUtils.hexStr2Bytes(view.code)[0]
                            bytes[4] = 0
                            totalByte = 0
                            for (byte in bytes) {
                                totalByte = totalByte + byte
                            }
                            bytes[4] = totalByte.toByte()
                            msg.obj = bytes
                            sendHandler.handleMessage(msg)
                        }
                    }
                }, 0)
            }

            view.img?.let {
                EventBus.getDefault().post(BedImgEvent(it))
            }
        }

        //获取计算后的数组
        fun getFinalBytes(bytes: ByteArray): ByteArray {
            val len = bytes.size - 1
            totalByte = 0
            for (byte in bytes) {
                totalByte = totalByte + byte
            }
            bytes[len] = totalByte.toByte()
            return bytes
        }

        //按键弹起
        fun onActionUp(view: RmText) {
            frontHandler.removeCallbacksAndMessages(null)
            sendHandler.removeCallbacksAndMessages(null)
            cmdEnd(view)
        }


        //遍历view找到所有的RmImageView加上事件
        fun traverseView(view: View, list: List<AreaValue>) {
            if (view is ViewGroup) {
                for (i in 0 until view.childCount) {
                    traverseView(view.getChildAt(i), list)
                }
                return
            }

            if (view is RmText && view.code != null) {
                view.setOnTouchListener(null)
                view.visibility = View.GONE
                for (cmd in list) {
                    if (cmd.code.equals(view.code, ignoreCase = true)) {
                        view.visibility = View.VISIBLE
                        view.setOnTouchListener(onTouchListener)
                    }
                }
            }
        }


        //保存界面编号
//        @Synchronized
//        fun saveLocalInterface(bleAddress: String, interfaceNo: String): Boolean {
//            val edit = context.getSharedPreferences(BLE_INTERFACE, MODE_PRIVATE).edit()
//            edit.putString(bleAddress, interfaceNo)
//            return edit.commit()
//        }
//
//        //读取界面编号
//        @Synchronized
//        fun readLocalInterface(bleAddress: String): String? {
//            val sp = context.getSharedPreferences(BLE_INTERFACE, MODE_PRIVATE)
//            return sp.getString(bleAddress, null)
//        }

        fun inRangeOfView(view: View, screenX: Int, screenY: Int): Boolean {
            val location = IntArray(2)
            view.getLocationOnScreen(location)
            val left = location[0]
            val top = location[1]
            val right = left + view.measuredWidth
            val bottom = top + view.measuredHeight
            return screenX < left || screenX > right || screenY < top || screenY > bottom
        }

        @Synchronized
        fun updateGroupValueSend(bleRssiDevice: BleRssiDevice, isSend: Boolean): Boolean {
//            var isFind  = false
//            for((key, value) in groupMap) {
//                for(i in 0 until  value.groupValueList.size) {
//                    val groupValue = value.groupValueList.get(i)
//                    if(groupValue.bleRssiDevice.bleAddress.equals(tGroupValue.bleRssiDevice.bleAddress)) {
//                        groupValue.isSend = isSend
//                        isFind = true
//                        break
//                    }
//                }
//                if(isFind) {
//                    break
//                }
//            }
            UuidUtil.curUuidMap.forEach {
                if (it.key.bleAddress.equals(bleRssiDevice.bleAddress)) {
                    it.key.isSend = isSend
                }
            }

            if (SpUtil.putHashMapData(context, SECTION_BLE_GROUP, KEY_GROUP, connectMap)) {
                return true
            }
            return false
        }

        //添加groupKey条目
        @Synchronized
        fun addGroupKey(context: Context, groupName: String, groupType: Int): Long {
            val groupId = System.currentTimeMillis()
//            val groupId = SimpleDateFormat("yyyyMMddHHmmss").format(Date())
            val groupKey = ConnectKey(groupId, groupType, groupName)
//                        val groupValueList = ArrayList<GroupValue>()
//                        groupValueList.add(GroupValue("A8-1E-84-B0-A1-65", "设备1"))
//                        groupValueList.add(GroupValue("A8-1E-84-B0-A1-66", "设备2"))
            val bleGroup = ConnectGroup(groupKey, ArrayList())
            connectMap.put(groupId.toString(), bleGroup)
            if (SpUtil.putHashMapData(context, SECTION_BLE_GROUP, KEY_GROUP, connectMap)) {
                return groupId
            }
            return 0L
        }

        //删除groupKey条目
        @Synchronized
        @JvmStatic
        fun deleteGroupKey(groupKey: ConnectKey): Boolean {
            connectMap.forEach {
                if (groupKey.equals(it.value.connectKey)) {
                    connectMap.remove(it.key)
                    if (SpUtil.putHashMapData(context, SECTION_BLE_GROUP, KEY_GROUP, connectMap)) {
                        return true
                    }
                }
            }
            return false
        }

        //删除groupValue列表
        @Synchronized
        @JvmStatic
        fun deleteGroupValueList(
            groupId: String,
            groupValueList: ArrayList<ConnectValue>
        ): Boolean {
            connectMap.forEach {
                if (it.value.connectKey.id.equals(groupId)) {
                    it.value.connectValueList.clear()
                    if (SpUtil.putHashMapData(context, SECTION_BLE_GROUP, KEY_GROUP, connectMap)) {
                        return true
                    }
                }
            }
            return false
        }


        //添加groupValuel列表
        @Synchronized
        fun addGroupValueList(
            context: Context,
            groupId: Long,
            tGroupValueList: ArrayList<ConnectValue>
        ): Boolean {
            connectMap.forEach {
                //取消组选择
                val groupKey = it.value.connectKey
                val groupValueList = it.value.connectValueList
                //取消组子列表选择
                if (groupKey.id.equals(groupId)) {
                    for (i in 0 until tGroupValueList.size) {
                        val bleAddress = tGroupValueList.get(i).bleRssiDevice.bleAddress
                        if (!isContainAddress(bleAddress, groupValueList)) {
                            groupValueList.add(tGroupValueList.get(i))
                        }
                    }
                    if (SpUtil.putHashMapData(context, SECTION_BLE_GROUP, KEY_GROUP, connectMap)) {
                        return true
                    }
                }
            }
            return false
        }

        private fun isContainAddress(
            bleAddress: String,
            groupValueList: ArrayList<ConnectValue>
        ): Boolean {
            groupValueList.forEach {
                if (it.bleRssiDevice.bleAddress.equals(bleAddress)) {
                    return true
                }
            }
            return false
        }

        //判断是否可以发送
        fun isDeviceSend(device: BleRssiDevice): Boolean {
            connectMap.forEach {
                it.value.connectValueList.forEach {
                    if (it.bleRssiDevice.bleAddress.equals(device.bleAddress)) {
                        return it.isSend
                    }
                }
            }
            return true
        }


        //读取groupMap信息
        @Synchronized
        fun readGroupMap(context: Context): Boolean {
            val map = SpUtil.getHashMapData(
                context,
                SECTION_BLE_GROUP,
                KEY_GROUP,
                ConnectGroup::class.java
            )
            if (map != null) {
                connectMap.putAll(map)
                return true
            }
            return false
        }


        //读取单一设备界面号
        fun readSingleSurfaceNo(bleAddress: String): String {
            return SpUtil.getData(context, SpUtil.SECTION_GROUP_ID, bleAddress, "") as String
        }

        //获取界面编号
        fun readGroupSurfaceNo(groupId: Long): String {
            return SpUtil.getData(
                context,
                SpUtil.SECTION_GROUP_ID,
                groupId.toString(),
                ""
            ) as String
        }

        //            var interfaceNo = ""
//            if (lastGroupType == GROUP_TYPE_NONE) {
//                if (lastBleDeviceList.size > 0) {
//                    interfaceNo = SpUtil.getData(context, SpUtil.SECTION_GROUP_ID, lastBleDeviceList.get(0).bleAddress, "") as String
//                }
//            } else {
//                if (lastGroupId != 0L) {
//                    interfaceNo = SpUtil.getData(context, SpUtil.SECTION_GROUP_ID, lastGroupId.toString(), "") as String
//                }
//            }

//        fun saveInterfaceNo(intefaceNo: String): Boolean {
//            if (lastGroupType == GROUP_TYPE_NONE) {
//                return SpUtil.putData(context, SpUtil.SECTION_GROUP_ID, lastBleDeviceList.get(0).bleAddress, intefaceNo)
//            } else {
//                return SpUtil.putData(context, SpUtil.SECTION_GROUP_ID, lastGroupId.toString(), intefaceNo)
//            }
//        }

        fun saveSingleSurfaceNo(bleAddress: String, intefaceNo: String): Boolean {
            return SpUtil.putData(context, SpUtil.SECTION_GROUP_ID, bleAddress, intefaceNo)
        }

        fun saveGroupInterfaceNo(groupId: Long, intefaceNo: String): Boolean {
            return SpUtil.putData(context, SpUtil.SECTION_GROUP_ID, groupId.toString(), intefaceNo)
        }

        //连接前准备
        fun prepareConnect(
            bleDeviceList: ArrayList<BleRssiDevice>,
            groupType: Int = EConnect.CONNECT_SINGLE.data,
            groupId: Long = 0L,
            isNew: Boolean = false
        ) {
            lastConnect.connectType = groupType
            lastConnect.connectId = groupId
            lastConnect.bleDeviceList.clear()
            lastConnect.bleDeviceList.addAll(bleDeviceList)
//            lastConnect.fragExtraList.clear()
            lastConnect.isNew = isNew

            lastConnect.isMotorInit = false
            lastConnect.isMemInit = false
            lastConnect.isMasInit = false
            lastConnect.isAlarmInit = false
            lastConnect.isLedInit = false
            lastConnect.isAromaInit = false
        }

        fun calcLastByte(bytes: ByteArray): ByteArray {
            totalByte = 0
            for (byte in bytes) {
                totalByte = totalByte + byte
            }
            bytes[bytes.size - 1] = totalByte.toByte()
            return bytes
        }


        //批量发送线程任务
//        fun runThreadTask(arrayBlockingQueue: ArrayBlockingQueue<TaskData>, uiTask: Runnable?) {
//            if (arrayBlockingQueue.size == 0) {
//                if (uiTask != null) {
//                    ThreadUtils.ui(
//                        uiTask
//                    )
//                }
//                return
//            }
//
//            val threadPoolExecutor = ThreadPoolExecutor(
//                1,          //核心处理线程数
//                1,      //最大线程数
//                1,          //
//                TimeUnit.SECONDS,          //存活时间
//                LinkedBlockingDeque(arrayBlockingQueue.size),   //等待区线程数量
//                Executors.defaultThreadFactory(),           //默认
//                ThreadPoolExecutor.DiscardPolicy()      //拒绝回调策略
//            )
//
//            arrayBlockingQueue.forEach {
//                val taskData = arrayBlockingQueue.poll()
//                taskData.task.run()
//                TimeUnit.MILLISECONDS.sleep(taskData.delayMs)
//                LogUtil.e(Thread.currentThread().name + "=  出去了")
//            }
//
//            threadPoolExecutor.shutdown();
//            if (uiTask != null) {
//                threadPoolExecutor.awaitTermination(1, TimeUnit.HOURS);
//                ThreadUtils.ui(
//                    uiTask
//                )
//            }
//        }
    }
}